package com.pfs.internal.timestamp.repositories;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;

import com.pfs.internal.timestamp.actions.TimeStampAction;
import com.pfs.internal.timestamp.entities.CardHolder;
import com.pfs.internal.timestamp.entities.HWIndependentDevices;
import com.pfs.internal.timestamp.entities.History;

public class CardHolderRepositoryImpl extends BaseRepository<CardHolder, Integer> implements CardHolderRepository {
	public List<CardHolder> findAllPfs() {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<CardHolder> myquery = cb.createQuery(CardHolder.class);
		Root<CardHolder> root = myquery.from(CardHolder.class);

		ParameterExpression<Integer> deletedParamExp = cb.parameter(Integer.class, "deleted");
		ParameterExpression<String> lastNameParamExp = cb.parameter(String.class, "lastName");

		Predicate deletedPredicate = cb.equal(root.<Integer> get("deleted"), deletedParamExp);
		Predicate lastNameParamPredicate = cb.like(root.<String> get("lastName"), lastNameParamExp);

		myquery.select(root).where(cb.and(deletedPredicate, lastNameParamPredicate));
		TypedQuery<CardHolder> someHWDevices = entityManager.createQuery(myquery);
		someHWDevices.setParameter("deleted", 0);
		someHWDevices.setParameter("lastName", "PFS-%");

		return someHWDevices.getResultList();
	}

	public List<CardHolder> findPfsNoHandReg() {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<CardHolder> myquery = cb.createQuery(CardHolder.class);
		Root<CardHolder> root = myquery.from(CardHolder.class);

		ParameterExpression<Integer> deletedParamExp = cb.parameter(Integer.class, "deleted");
		ParameterExpression<String> lastNameParamExp = cb.parameter(String.class, "lastName");

		Predicate deletedPredicate = cb.equal(root.<Integer> get("deleted"), deletedParamExp);
		Predicate lastNameParamPredicate = cb.like(root.<String> get("lastName"), lastNameParamExp);

		myquery.select(root).where(cb.and(deletedPredicate, lastNameParamPredicate));
		TypedQuery<CardHolder> someHWDevices = entityManager.createQuery(myquery);
		someHWDevices.setParameter("deleted", 0);
		someHWDevices.setParameter("lastName", "PFS-%");

		return someHWDevices.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<CardHolder> searchTracks(Map<String, Object> mapParams) {
		String account = null;
		Date fromDate = null, toDate = null;
		if (mapParams.containsKey(TimeStampAction.ACCOUNT) && mapParams.get(TimeStampAction.ACCOUNT) != null) {
			account = (String) mapParams.get(TimeStampAction.ACCOUNT);
		}
		if (mapParams.containsKey(TimeStampAction.FROM_DATE) && mapParams.get(TimeStampAction.FROM_DATE) != null) {
			fromDate = (Date) mapParams.get(TimeStampAction.FROM_DATE);
		}
		if (mapParams.containsKey(TimeStampAction.TO_DATE) && mapParams.get(TimeStampAction.TO_DATE) != null) {
			toDate = (Date) mapParams.get(TimeStampAction.TO_DATE);
		}
		Query query = entityManager.createQuery("select c.recordID, c.firstName, c.lastName, c.histories from CardHolder c join fetch c.histories h where c.deleted=0 and lower(c.lastName) like :lastName and h.timeStamp >= :fromDate and h.timeStamp <= :toDate");
		query.setParameter("lastName", "%" + account.toLowerCase() + "%");
		query.setParameter("fromDate", fromDate);
		query.setParameter("toDate", toDate);
		List<CardHolder> list = query.getResultList();
		return list;
	}
}
